<template>
  <Dialog :title="title" :model-value="visible" width="1300px" :before-close="closeForm">
    <el-tabs v-model="active" @tab-change="tabChange">
      <el-tab-pane label="基础信息" name="basic">
        <Form
          :schema="schema"
          :model="node"
          @register="formRegister"
          :isCol="false"
          label-width="200px"
          :rules="rules"
        />
        <div v-if="readonly == false" style="text-align: center; width: 100%">
          <el-space>
            <BaseButton type="primary" @click="save">保存</BaseButton>
            <BaseButton @click="resetForm">重置</BaseButton>
          </el-space>
        </div>
      </el-tab-pane>
      <el-tab-pane label="出入策略" name="intoOut">
        <intoOutEdit
          :def-form-id="defFormId"
          :readonly="readonly"
          :source="source"
          :flow-id="flowId"
          :node-id="nodeId"
          :isload="active == 'intoOut'"
          @change="saveInto"
        />
      </el-tab-pane>
      <el-tab-pane label="表单配置" name="formEdit">
        <nodeFormEdit
          :readonly="readonly"
          :def-form-id="defFormId"
          :source="source"
          :flow-id="flowId"
          :node-id="nodeId"
          :is-load="active == 'formEdit'"
          @refresh="saveForm"
        />
      </el-tab-pane>
      <el-tab-pane label="表单权限" name="formPower">
        <nodeFormPower
          :readonly="readonly"
          :flow-id="flowId"
          :form-id="curFormId"
          :is-allow-edit="source.IsAllowEdit"
          :node-id="nodeId"
          :is-load="active == 'formPower'"
        />
      </el-tab-pane>
      <el-tab-pane label="审批人" name="auditActor">
        <whileAuditActor
          :flow-id="flowId"
          :readonly="readonly"
          :node-id="nodeId"
          v-model:show="show"
          :is-load="active == 'auditActor'"
          @change="actorIsRefresh = true"
        />
      </el-tab-pane>
      <el-tab-pane label="审批事件" name="nodeEv">
        <nodeEventEdit
          :filter-event="fliterEvents"
          :readonly="readonly"
          :flow-id="flowId"
          :node-id="nodeId"
          :node-event="source.NodeEvent"
          :is-load="active == 'nodeEv'"
        />
      </el-tab-pane>
      <el-tab-pane label="抄送配置" name="auditMsg">
        <auditMsgEdit
          :flow-id="flowId"
          :node-id="nodeId"
          :readonly="readonly"
          :nodes="backNodes"
          :is-load="active == 'auditMsg'"
        />
      </el-tab-pane>
    </el-tabs>
  </Dialog>
</template>

<script>
import { EnumDic, AuditButton } from '@/flow/config/flowConfig'
import * as flowNodeApi from '@/flow/api/flowNode'
import intoOutEdit from './intoOutEdit.vue'
import auditMsgEdit from './auditMsgEdit.vue'
import nodeEventEdit from './nodeEventEdit.vue'
import whileAuditActor from './whileAuditActor.vue'
import nodeFormEdit from './nodeFormEdit.vue'
import nodeFormPower from './nodeFormPower.vue'
import { Dialog } from '@/components/Dialog/'
import { Form } from '@/components/Form'
import { useForm } from '@/hooks/web/useForm'
const { formRegister, formMethods } = useForm()
export default {
  components: {
    auditMsgEdit,
    intoOutEdit,
    nodeEventEdit,
    whileAuditActor,
    nodeFormEdit,
    nodeFormPower,
    Dialog,
    Form
  },
  props: {
    nodeId: {
      type: String,
      default: null
    },
    defFormId: {
      type: String,
      default: null
    },
    flowId: {
      type: String,
      default: null
    },
    readonly: {
      type: Boolean,
      default: false
    },
    auditType: {
      type: Number,
      default: null
    },
    nodes: {
      type: Array,
      default: null
    },
    visible: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      EnumDic,
      active: 'basic',
      show: null,
      curFormId: null,
      source: {},
      schema: [],
      title: null,
      node: {},
      isRefresh: false,
      actorIsRefresh: false,
      backNodes: [],
      auditFunc: [
        {
          key: 'OpinionMust',
          label: '审批意见必填'
        },
        {
          key: 'IsSign',
          label: '需手写签名'
        },
        {
          key: 'IsUpFile',
          label: '允许上传附件'
        },
        {
          key: 'IsUpFileSign',
          label: '对上传附件签名'
        },
        {
          key: 'IsAllowCancel',
          label: '允许撤回'
        }
      ],
      rules: {
        NodeName: [
          {
            required: true,
            message: '节点名称不能为空！',
            trigger: 'blur'
          }
        ],
        AuditButton: [
          {
            required: true,
            message: '审批按钮不能为空！',
            trigger: 'blur'
          }
        ]
      }
    }
  },
  watch: {
    visible: {
      handler(val) {
        if (val && this.nodeId != null) {
          this.reset()
        }
      },
      immediate: true
    },
    defFormId: {
      handler(val) {
        if (val && this.source.FormId == null) {
          this.curFormId = val
        }
      },
      immediate: false
    },
    nodeId: {
      handler(val) {
        if (val && this.visible) {
          this.reset()
        }
      },
      immediate: false
    },
    nodes: {
      handler(val) {
        if (val) {
          this.backNodes = val.filter((c) => c.NodeType !== 0 && c.NodeType !== 3)
        }
      },
      immediate: true
    }
  },
  mounted() {},
  methods: {
    formRegister,
    initScheme() {
      const list = [
        {
          field: 'NodeCode',
          label: '节点编号',
          component: 'Label'
        },
        {
          field: 'NodeName',
          label: '节点名称',
          component: 'Input',
          componentProps: {
            readonly: this.readonly,
            clearable: true,
            placeholder: '节点名称'
          }
        },
        {
          field: 'buttons',
          label: '审批按钮',
          component: 'EnumItem',
          componentProps: {
            dicKey: EnumDic.AuditButton,
            readonly: this.readonly,
            sysHead: 'flow',
            filters: [0, 8, 256, 512],
            placeholder: '审批按钮',
            multiple: true,
            mode: 'button',
            on: {
              change: (val) => {
                this.node.buttons = val
                this.initScheme()
              }
            }
          }
        }
      ]
      list.push({
        field: 'FuncList',
        label: '审核功能开关',
        component: 'CheckboxGroup',
        componentProps: {
          disabled: this.readonly,
          options: this.auditFunc
        }
      })
      list.push({
        field: 'LimitTime',
        label: '审核限制时间',
        component: 'InputNumber',
        componentProps: {
          disabled: this.readonly,
          placeholder: '审核限制时间(分钟)',
          clearable: true,
          on: {
            change: (val) => {
              this.node.LimitTime = val
              this.initScheme()
            }
          }
        }
      })
      if (this.node.LimitTime != null && this.node.LimitTime !== 0) {
        list.push({
          field: 'TimeOutOpt',
          label: '超时处理方式',
          component: 'EnumItem',
          componentProps: {
            dicKey: EnumDic.FlowTimeOutOpt,
            readonly: this.readonly,
            sysHead: 'flow',
            filters: [0],
            placeholder: '超时处理方式',
            on: {
              change: (val) => {
                this.node.TimeOutOpt = val
                this.initScheme()
              }
            }
          }
        })
      }
      if (this.node.TimeOutOpt >= 4) {
        list.push({
          field: 'ToEmpId',
          label: this.timeOutOpt[node.TimeOutOpt],
          component: 'EmpInput',
          componentProps: {
            readonly: this.readonly,
            placeholder: '选择' + this.timeOutOpt[node.TimeOutOpt],
            clearable: true
          }
        })
      }
      list.push({
        field: 'ProgressVal',
        label: '进度值',
        component: 'InputNumber',
        componentProps: {
          disabled: this.readonly,
          min: 0,
          max: 100,
          step: 1,
          placeholder: '进度值',
          clearable: true
        }
      })
      if (this.node.buttons.includes(64)) {
        list.push({
          field: 'BackNodeId',
          label: '回退的节点',
          component: 'Select',
          componentProps: {
            disabled: this.readonly,
            options: this.backNodes,
            props: {
              label: 'NodeName',
              value: 'Id'
            },
            placeholder: '回退的节点',
            clearable: true
          }
        })
        list.push({
          field: 'BackMethod',
          label: '回退的处理方式',
          component: 'EnumItem',
          componentProps: {
            dicKey: EnumDic.FlowBackMethod,
            readonly: this.readonly,
            sysHead: 'flow',
            placeholder: '回退的处理方式'
          }
        })
      }
      list.push({
        field: 'NoticeRange',
        label: '消息通知范围',
        component: 'EnumItem',
        componentProps: {
          dicKey: EnumDic.FlowMsgNoticeRange,
          readonly: this.readonly,
          sysHead: 'flow',
          placeholder: '消息通知范围'
        }
      })
      list.push({
        field: 'Show',
        label: '审批说明',
        component: 'Input',
        componentProps: {
          maxlength: 100,
          readonly: this.readonly,
          clearable: true,
          placeholder: '审批说明'
        }
      })
      this.schema = list
    },
    saveForm(data) {
      this.source.FormId = data.FormId == null ? null : data.FormId
      this.source.IsAllowEdit = data.IsAllowEdit
      this.curFormId = data.FormId == null ? this.defFormId : data.FormId
    },
    saveInto(data) {
      this.source = Object.assign(this.source, data)
    },
    fliterEvents(val) {
      return val !== 2 && val !== 4 && val !== 8 && val !== 128
    },
    tabChange(e) {
      if (this.active === 'basic') {
        this.resetBase(this.source)
      }
    },
    async save() {
      const data = await formMethods.validate()
      if (data == null) {
        return
      }
      this.set(Object.assign({}, data))
    },
    async set(data) {
      let btn = 0
      data.buttons.forEach((c) => {
        btn += parseInt(c)
      })
      data.AuditType = 1
      data.AuditButton = btn
      delete data.buttons
      this.initFunc(data)
      const res = await flowNodeApi.Set(this.nodeId, data)
      this.$message({
        message: '更新成功!',
        type: 'success'
      })
      if (res) {
        this.isRefresh = true
        this.source = Object.assign(this.source, data)
      }
    },
    initFunc(data) {
      this.auditFunc.forEach((c) => {
        data[c.key] = data.FuncList.includes(c.key)
      })
      delete data.FuncList
    },
    async reset() {
      this.isRefresh = false
      this.actorIsRefresh = false
      const data = await flowNodeApi.Get(this.nodeId)
      this.active = 'basic'
      data.buttons = []
      if (data.FormId == null) {
        this.curFormId = this.defFormId
      } else {
        this.curFormId = data.FormId
      }
      if (data.AuditButton != null) {
        AuditButton.forEach((c) => {
          if ((c.value & data.AuditButton) === c.value) {
            data.buttons.push(c.value)
          }
        })
      }
      this.title = '编辑循环节点：' + data.NodeName
      this.source = data
      this.resetBase(data)
    },
    closeForm() {
      this.$emit('update:visible', false)
      this.$emit('close', {
        isUpdate: this.isRefresh,
        node: this.node,
        showIsUpdate: this.actorIsRefresh,
        show: this.show
      })
    },
    resetForm() {
      this.resetBase(this.source)
    },
    resetBase(data) {
      const funcList = []
      if (data.IsSign) {
        funcList.push('IsSign')
      }
      if (data.IsUpFile) {
        funcList.push('IsUpFile')
      }
      if (data.IsUpFileSign) {
        funcList.push('IsUpFileSign')
      }
      if (data.IsAllowCancel) {
        funcList.push('IsAllowCancel')
      }
      if (data.OpinionMust) {
        funcList.push('OpinionMust')
      }
      this.node = {
        NodeType: data.NodeType,
        NodeName: data.NodeName,
        LimitTime: data.LimitTime,
        TimeOutOpt: data.TimeOutOpt,
        FuncList: funcList,
        ProgressVal: data.ProgressVal,
        BackMethod: data.BackMethod,
        NoticeRange: data.NoticeRange,
        buttons: data.buttons,
        ToEmpId: data.ToEmpId,
        BackNodeId: data.BackNodeId,
        Show: data.Show
      }
      formMethods.setValues(this.node)
      this.initScheme()
    }
  }
}
</script>
